Hands-On Exercise 3: Spatial Point Patterns Analysis

Published

January 27, 2023

Modified

January 27, 2023

Import packages

pacman::p_load(maptools, sf, raster, spatstat, tmap)

Importing Dataset

Spatial Data

childcare_sf <- st_read("data/geospatial/childcare.geojson") %>%
  st_transform(crs = 3414)
Reading layer `childcare' from data source 
  `C:\Jenpoer\IS415-GAA\Hands-On-Exercises\chapter-04\data\geospatial\childcare.geojson' 
  using driver `GeoJSON'
Simple feature collection with 1545 features and 2 fields
Geometry type: POINT
Dimension:     XYZ
Bounding box:  xmin: 103.6824 ymin: 1.248403 xmax: 103.9897 ymax: 1.462134
z_range:       zmin: 0 zmax: 0
Geodetic CRS:  WGS 84
# Todo: sg_sf
mpsz_sf <- st_read(dsn = "../chapter-02/data/geospatial/master-plan-2014-subzone-boundary-web-shp",
                   layer = "MP14_SUBZONE_WEB_PL")
Reading layer `MP14_SUBZONE_WEB_PL' from data source 
  `C:\Jenpoer\IS415-GAA\Hands-On-Exercises\chapter-02\data\geospatial\master-plan-2014-subzone-boundary-web-shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 323 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2667.538 ymin: 15748.72 xmax: 56396.44 ymax: 50256.33
Projected CRS: SVY21

Retrieve referencing system information of geospatial data

Childcare: EPSG 3414, Projection CRS SVY21

st_crs(childcare_sf)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

MPSZ: EPSG 9001, Projection CRS SVY21

st_crs(mpsz_sf)
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

Assign correct crs information

MPSZ

We only need to change the crs because it is already the correct projection.

mpsz_sf <- st_set_crs(mpsz_sf, 3414)

Mapping

tmap_mode("plot")
tm_shape(mpsz_sf) +
  tm_polygons() +
  tm_shape(childcare_sf) +  
  tm_dots()

tmap_mode('view')
tm_shape(childcare_sf)+
  tm_dots()
tmap_mode("plot")

Geospatial Data Wrangling

Conversion from sf’s simple feature data frame to sp’s Spatial* class

childcare <- as_Spatial(childcare_sf)
mpsz <- as_Spatial(mpsz_sf)
summary(childcare)
Object of class SpatialPointsDataFrame
Coordinates:
               min      max
coords.x1 11203.01 45404.24
coords.x2 25667.60 49300.88
coords.x3     0.00     0.00
Is projected: TRUE 
proj4string :
[+proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1
+x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0
+units=m +no_defs]
Number of points: 1545
Data attributes:
     Name           Description       
 Length:1545        Length:1545       
 Class :character   Class :character  
 Mode  :character   Mode  :character  
summary(mpsz)
Object of class SpatialPolygonsDataFrame
Coordinates:
        min      max
x  2667.538 56396.44
y 15748.721 50256.33
Is projected: TRUE 
proj4string :
[+proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1
+x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0
+units=m +no_defs]
Data attributes:
    OBJECTID       SUBZONE_NO      SUBZONE_N          SUBZONE_C        
 Min.   :  1.0   Min.   : 1.000   Length:323         Length:323        
 1st Qu.: 81.5   1st Qu.: 2.000   Class :character   Class :character  
 Median :162.0   Median : 4.000   Mode  :character   Mode  :character  
 Mean   :162.0   Mean   : 4.625                                        
 3rd Qu.:242.5   3rd Qu.: 6.500                                        
 Max.   :323.0   Max.   :17.000                                        
    CA_IND           PLN_AREA_N         PLN_AREA_C          REGION_N        
 Length:323         Length:323         Length:323         Length:323        
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
   REGION_C           INC_CRC            FMEL_UPD_D             X_ADDR     
 Length:323         Length:323         Min.   :2014-12-05   Min.   : 5093  
 Class :character   Class :character   1st Qu.:2014-12-05   1st Qu.:21864  
 Mode  :character   Mode  :character   Median :2014-12-05   Median :28465  
                                       Mean   :2014-12-05   Mean   :27257  
                                       3rd Qu.:2014-12-05   3rd Qu.:31674  
                                       Max.   :2014-12-05   Max.   :50425  
     Y_ADDR        SHAPE_Leng        SHAPE_Area      
 Min.   :19579   Min.   :  871.5   Min.   :   39438  
 1st Qu.:31776   1st Qu.: 3709.6   1st Qu.:  628261  
 Median :35113   Median : 5211.9   Median : 1229894  
 Mean   :36106   Mean   : 6524.4   Mean   : 2420882  
 3rd Qu.:39869   3rd Qu.: 6942.6   3rd Qu.: 2106483  
 Max.   :49553   Max.   :68083.9   Max.   :69748299  

Conversion from Spatial* class to generic sp format (Spatial)

childcare_sp <- as(childcare, "SpatialPoints")
childcare_sp
class       : SpatialPoints 
features    : 1545 
extent      : 11203.01, 45404.24, 25667.6, 49300.88  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

Conversion from generic sp format to spatstat’s ppp

childcare_ppp <- as(childcare_sp, "ppp")
childcare_ppp
Planar point pattern: 1545 points
window: rectangle = [11203.01, 45404.24] x [25667.6, 49300.88] units
plot(childcare_ppp)

summary(childcare_ppp)
Planar point pattern:  1545 points
Average intensity 1.91145e-06 points per square unit

*Pattern contains duplicated points*

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [11203.01, 45404.24] x [25667.6, 49300.88] units
                    (34200 x 23630 units)
Window area = 808287000 square units
Duplicated points may be problematic in spatial point patterns analysis. This is because the statistical methodology used for spatial point patterns analysis assumes that points cannot be coincident.

Handling duplicated points

Check for duplication

any(duplicated(childcare_ppp))
[1] TRUE

Count the number of coincident points

sum(multiplicity(childcare_ppp) > 1)
[1] 128

View locations of duplicate point events

tmap_mode('view')
tm_shape(childcare) +
  tm_dots(alpha=0.4, 
          size=0.05)

We can see duplicate points because they are more opaque (multiple points overlapping exactly on the same spot).

tmap_mode('plot')

There are three approaches to this problem.

  1. Delete the duplicates: But some useful point events will be lost.
  2. Jittering: Add a small perturbation to the duplicate points so that they do not occupy the exact same space.
  3. Marks: make each point “unique” and then attach the duplicates of the points to the patterns as marks (attributes of the points). Then, we need analytical techniques that take into account these marks.

This code implements jittering.

childcare_ppp_jit <- rjitter(childcare_ppp,
                             retru=TRUE,
                             nsim=1,
                             drop=TRUE)
any(duplicated(childcare_ppp_jit))
[1] FALSE

Creating spatstat’s owin object

spatstat’s owin object is specially designed to represent a polygonal region.

Todo: Implement after finding the dataset